home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
BTNGO.ZIP
/
BTNGOC.ZIP
/
ITEMDATA.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-28
|
19KB
|
519 lines
#include<windows.h>
#include<ctype.h>
#include"wstring.hpp"
#include"itemdata.hpp"
#ifdef DEBUG_SCREENS
extern WinMessageString screen;
#endif
extern WinMessageString errscreen;
extern unsigned int winver;
/////////////////////////////////////
// defines
#define CFP(x) (&((char __far *)memptr)[x]) // create char __far * x bytes into buffer
#define CFP2(x) (&((char __far *)memptr2)[x]) // create char __far * x bytes into buffer
/////////////////////////////////////
// local data types
struct GroupInfo{
WORD name;
WORD executable;
WORD executable_with_path;
WORD parameters;
WORD default_directory;
WORD minimized;
};
struct GroupFileHeader{
char cIdentifier[4];
WORD wCheckSum;
WORD cbGroup;
WORD nCmdShow;
RECT rcNormal;
POINT ptMin;
WORD pName;
WORD wLogPixelsX;
WORD wLogPixelsY;
BYTE bBitsPerPixel;
BYTE bPlanes;
WORD wReserved;
WORD cItems;
};
struct ItemData{
POINT pt;
WORD iIcon; // 0 if normal, 1 if minimized
WORD cbResource;
WORD cbANDPlane;
WORD cbXORPlane;
WORD pHeader;
WORD pANDPlane;
WORD pXORPlane;
WORD pName;
WORD pCommand;
WORD pIconPath; // 0 or ptr to initial path
};
struct TagData{
WORD wID;
WORD wItem;
WORD cb;
union{
char cnext[1];
int inext;
}next;
};
struct IconHeader{ // pointed to by ItemData.pHeader
int xHotSpot;
int yHotSpot;
int cx; // icon width
int cy; // icon height
int cbWidth; // bytes per row including WORD alignment
BYTE bPlanes; // nbr planes
BYTE bBitsPixel; // bits per pixel
};
/////////////////////////////////////
// GroupFile member functions
GroupFile::GroupFile(char *p){
opened=0;
items_to_read=0;
tag_bytes=0;
memhandle=NULL;
memptr=NULL;
memhandle2=NULL;
memptr2=NULL;
got_icon_default_data=0;
set_filename(p);
}
GroupFile::~GroupFile(){
if(opened)_lclose(hf);
if(memhandle!=NULL){
if(memptr!=NULL)GlobalUnlock(memhandle);
GlobalFree(memhandle);
}
if(memhandle2!=NULL){
if(memptr2!=NULL)GlobalUnlock(memhandle2);
GlobalFree(memhandle2);
}
#ifdef DEBUG_SCREENS
screen<<grpfil<<" destructed\n";
screen.show();
#endif
}
void GroupFile::set_filename(char *p){
error_condition_exists=(NULL==(grpfil=p))?1:0;
}
int GroupFile::openfile(){
if(error())return 0;
// assume failure so can just return
error_condition_exists=1;
if(opened)return 0;
opened=((hf=_lopen(grpfil,READ))==HFILE_ERROR)?0:1;
if(!opened)return 0;
filebytes=_llseek(hf,0,2); // go to end of file
if(filebytes==HFILE_ERROR||_llseek(hf,0,0)==HFILE_ERROR)return 0; // go to beginning
if(filebytes>60000L){
errscreen<<"Group file is too large. Aborting.\n";
return 0;
}
if(filebytes<(sizeof(GroupFileHeader)+2+sizeof(ItemData)+sizeof(IconHeader))){
errscreen<<"Group file is empty or too small. Aborting.\n";
return 0;
}
if(NULL==(memhandle=GlobalAlloc(GMEM_FIXED,filebytes))){
errscreen<<"Could not allocate memory\n";
return 0;
}
if(NULL==(memptr=GlobalLock(memhandle))){
errscreen<<"Could not lock memory\n";
return 0;
}
if(_lread(hf,memptr,(UINT)filebytes)!=(UINT)filebytes){
errscreen<<"Could not read group file. Aborting.\n";
return 0;
}
GroupFileHeader __far *p=(GroupFileHeader __far *)memptr;
if(p->cIdentifier[0]!='P'||p->cIdentifier[1]!='M'||
p->cIdentifier[2]!='C'||p->cIdentifier[3]!='C'){
errscreen<<"Group file corrupted. Aborting.\n";
return 0;
}
pItemOffset=(int __far *)&p[1];
{
int ok=0;
for(;;){
WORD x;
if(p->cItems<1)break;
for(x=0;x<p->cItems;x++){
if(pItemOffset[x]!=0){
ok=1;
break;
}
}
break;
}
if(!ok){
errscreen<<"Group file is empty. Aborting.";
return 0;
}
}
_lclose(hf);
opened=0;
error_condition_exists=0;
return 1;
}
void GroupFile::readheader(){
if(error())return;
GroupFileHeader _far *p=(GroupFileHeader __far *)memptr;
// pItemOffset=(int *)&((GroupFileHeader *)memptr)[1];
items_to_read=p->cItems;
#ifdef DEBUG_SCREENS
screen<<"Group name is "<<CFP(p->pName)<<"\n";
#endif
// now, if in Win 3.1, associate tag data with items
// this is because the wItem part of TagData will become
// invalid (we'll need to sort the icons by position)
// so we'll use this convention:
// ItemData == TagData wID usage
// -------- ----------- -----------------------------
// iIcon 0x8103 0 if normal, 1 if minimized
// pIconPath 0x8101 0 or ptr to initial path
//
// pseudocode:
// set all iIcons to 0, pIconPaths to 0
// if in Windows 3.1 TagData may be present so
// for each TagData entry
// apply data to ItemData entry
// end for
// end if
{
int t;
ItemData __far *p;
for(t=0;t<items_to_read;t++){
if(pItemOffset[t]==0)continue;
p=(ItemData __far *)CFP(pItemOffset[t]);
p->iIcon=0;
p->pIconPath=0;
}
}
if(winver>=0x30A){
int keep_going=0;
GroupFileHeader __far *p=(GroupFileHeader __far *)memptr;
ItemData __far *q;
TagData __far *tdp;
if(filebytes>=(LONG)(p->cbGroup+6)){ // '6' sted sizeof(TagData) - sizeof(union)
tdp=(TagData __far *)CFP(p->cbGroup);
keep_going=1;
}
while(keep_going){
switch(tdp->wID){
case 0xFFFF: keep_going=0; break;
case 0x8101: // path in next.cnext
q=(ItemData __far *)CFP(pItemOffset[tdp->wItem]);
q->pIconPath=(WORD)(tdp->next.cnext-(char __far *)memptr);
break;
case 0x8103: // app should be minimized
q=(ItemData __far *)CFP(pItemOffset[tdp->wItem]);
q->iIcon=1;
break;
}
// '6' in next line is sizeof(TagData) - sizeof(union)
if((LONG)(((char __far *)tdp-(char __far *)memptr)+tdp->cb+6)>filebytes){
keep_going=0;
continue;
}
tdp=(TagData __far *)(((char __far *)tdp)+tdp->cb);
}
}
// ok now we can sort the item data by the icon's position
// so the group looks like it ought to
// use old'n'lame selection sort but it's good enough here...
if(items_to_read>1){
int min,x,left=items_to_read;
unsigned int temp;
unsigned int __far *p=(unsigned int __far *)pItemOffset;
while(left-->1){
for(x=0,min=0;x<=left;x++)if(second_lower(p[min],p[x]))min=x;
if(min!=0){temp=p[min];p[min]=*p;*p=temp;}
p++;
}
}
// now create the compacted version of the file
// first accumulate target size, then allocate space, then copy space
unsigned long size=0;
{
int left=items_to_read,found_items=0;
unsigned int __far *p=(unsigned int __far *)pItemOffset;
ItemData __far *i;
while(left&&*p){
i=(ItemData __far *)CFP(*p);
size+=sizeof(GroupInfo); // space for array entry
if(i->pName)size+=1+lstrlen(CFP(i->pName)); // space for entry's displayed name
if(i->pCommand)size+=1+lstrlen(CFP(i->pCommand)); // space for command line
if(i->pIconPath)size+=1+lstrlen(CFP(i->pIconPath)); // space for command path
p++;
left--;
found_items++;
}
items_to_read=found_items; // 'forget' about NULL entries
}
// no